<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>局域网文本共享</title>
  <link rel="icon" href="text-logo.png" type="image/x-icon">
  <style>
    body {
      height: calc(100% - 100px);
      margin: 0;
      padding: 0;
      font-family: Arial, sans-serif;
      font-size: 14px;
      background-color: #f6f6f6;
    }

    .chat-container {
      height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
    }

    .chat-window {
      width: 100%;
      height: calc(100% - 0px);
      background-color: #fff;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }

    .chat-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 50px;
      background-color: #4e8cff;
      color: #fff;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
      padding: 0 20px;
    }

    .chat-header h1 {
      margin: 0;
      font-size: 18px;
      display: inline-block;
    }

    .chat-body {
      flex: 1;
      overflow-y: scroll;
      padding: 10px 20px;
      display: flex;
      flex-direction: column;
    }

    .chat-body .message {
      display: flex;
      align-items: flex-start;
      margin-bottom: 4px;
    }

    .chat-body .message .content {
      flex: 1;
      background-color: #f6f6f6;
      border-radius: 5px;
      padding: 5px 10px;
      white-space: pre-wrap;
      word-break: break-word;
    }

    .chat-body .message .content a {
      color: #4e8cff;
      text-decoration: underline;
    }

    .chat-footer {
      display: flex;
      align-items: center;
      height: 50px;
      background-color: #f6f6f6;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
      padding: 0 10px;
    }

    .chat-footer input[type="text"] {
      flex: 1;
      height: 100%;
      border: none;
      outline: none;
      background-color: transparent;
      font-size: 14px;
      padding: 0 10px;
    }

    .chat-footer input[type="submit"] {
      width: 80px;
      height: 100%;
      border: none;
      outline: none;
      background-color: #4e8cff;
      color: #fff;
      cursor: pointer;
      font-size: 14px;
      margin:0px -10px 0px 0px;
    }

    .chat-body .message.sent {
      align-items: flex-end;
    }

    .chat-body .message.received .avatar {
      order: 2;
      margin-right: 0;
      margin-left: 10px;
    }

    .chat-body .message.received .content {
      order: 1;
    }

    .chat-header .settings-btn {
      margin-left: auto;
    }

    /* 手机竖屏 */
    @media screen and (max-width: 480px) {
      .chat-header {
        padding: 0 10px;
      }

      .chat-header h1 {
        font-size: 20px;
      }

      .chat-body {
        padding: 10px;
      }

      .chat-footer {
        padding: 0 5px;
      }

      .chat-footer input[type="text"] {
        font-size: 16px;
      }
      .chat-footer input[type="submit"] {
        font-size: 16px;
      }

      .modal {
        width: 240px;
      }
    }

    /* iPad 竖屏和横屏 */
    @media screen and (min-width: 481px) and (max-width: 1024px) {
      .chat-header {
        padding: 0 15px;
      }

      .chat-header h1 {
        font-size: 16px;
      }

      .chat-body {
        padding: 10px;
      }

      .chat-footer {
        padding: 0 10px;
      }
    }

    /* 设置按钮 */
    .settings-btn {
      cursor: pointer;
      margin-left: 10px;
    }

    /* 设置面板 */
    .settings-panel {
      position: absolute;
      top: 60px;
      right: 10px;
      width: 200px;
      background-color: #fff;
      border-radius: 5px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      display: none;
    }

    .settings-panel.active {
      display: block;
    }

    .settings-panel .settings-item {
      padding: 10px;
      border-bottom: 1px solid #f6f6f6;
      cursor: pointer;
    }

    .settings-panel .settings-item:last-child {
      border-bottom: none;
    }

    /* 夜间模式 */
    .dark-mode .chat-window {
      background-color: #222;
    }

    .dark-mode .chat-header {
      background-color: #111;
    }

    .dark-mode .chat-body {
      background-color: #333;
    }

    .dark-mode .chat-body .message .content {
      background-color: #3C3C3C;
    }
    .dark-mode .chat-footer {
      background-color: #111;
    }

    .dark-mode .chat-footer input[type="submit"] {
      background-color: #111;
    }

    .dark-mode .settings-panel {
      background-color: #111;
    }

    .dark-mode .chat-header, .dark-mode .chat-footer input[type="text"] {
      color: #fff;
    }

    /* 模态框 */
    .modal {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: #fff;
      border-radius: 10px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      padding: 20px;
      display: none;
      z-index: 9999;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
    }

    .confirm-button {
      /* 这里是确定按钮的样式 */
      text-align: center;
      text-decoration: none;
      display: inline-block;
      margin: 4px 10px;
      padding: 3px 6px;
      cursor: pointer;
      /* 设置按钮背景为透明 */
      background-color: transparent;
      border: 0px solid black; 
      border-radius: 5px;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
    }

    .cancel-button {
      /* 这里是取消按钮的样式 */
      text-align: center;
      text-decoration: none;
      display: inline-block;
      margin: 4px 10px;
      padding: 3px 6px;
      cursor: pointer;
      /* 设置按钮背景为透明 */
      background-color: transparent;
      border: 0px solid black;
      border-radius: 5px;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
    }

    .modal.active {
      display: block;
    }

    .modal input[type="text"] {
      width: -webkit-fill-available;
      height: 20px;
      margin-bottom: 10px;
      border: 1px solid #000;
      border-radius: 5px;
      padding: 5px;
      font-size: 14px;
    }

    .modal button {
      margin-right: 10px;
    }

    /*模态框震动效果*/
    .shake {
      animation: shake 0.5s linear;
    }

    @keyframes shake {
      0% {
        transform: translateX(0);
      }
      20% {
        transform: translateX(-5px);
      }
      40% {
        transform: translateX(5px);
      }
      60% {
        transform: translateX(-5px);
      }
      80% {
        transform: translateX(5px);
      }
      100% {
        transform: translateX(0);
      }
    }

    /*悬浮通知*/
    .notification {
      position: fixed;
      top: 1.2%;
      left: 50%;
      transform: translateX(-50%);
      padding: 10px;
      width: 90px;
      height: 12px;
      background-color: #4CAF50;
      color: #111;
      text-align: center;
      z-index: 9999;
      border-radius: 2px;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
    }

    .notification-content {
      font-weight: bold; /* 字体加粗 */
      font-size: 12px;
      line-height: 12px;
    }

    .notification.success {
      background-color: #F44336;
    }

    .notification.info {
      background-color: #f6f6f6;
    }

    .notification.warning {
      background-color: #FF9800;
    }

    .notification.error {
      background-color: #F44336;
    }

    /* 删除对话框 */
    .dialog {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
    }

    .dialog-content {
      background-color: white;
      padding: 20px;
      border-radius: 5px;
    }

    #confirmYes {
      /* 这里是确定按钮的样式 */
      float: right;
      text-align: center;
      text-decoration: none;
      display: inline-block;
      padding: 3px 6px;
      margin: 4px 8px;
      cursor: pointer;
      /* 设置按钮背景为透明 */
      background-color: transparent;
      border: 0px solid black; 
      border-radius: 5px;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
    }

    #confirmNo {
      /* 这里是取消按钮的样式 */
      float: right;
      text-align: center;
      text-decoration: none;
      display: inline-block;
      padding: 3px 6px;
      margin: 4px 10px;
      cursor: pointer;
      /* 设置按钮背景为透明 */
      background-color: transparent;
      border: 0px solid black;
      border-radius: 5px;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
    }

    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <div class="chat-container">
    <div class="chat-window">
      <div class="chat-header">
        <h1>文本共享</h1>
        <div class="settings-btn" onclick="toggleSettingsPanel()" style="font-size: 24px;">&#9881;</div>
      </div>
      <div class="chat-body"></div>
      <div class="chat-footer">
        <input type="text" placeholder="输入消息" />
        <input type="submit" value="发送" />
      </div>
    </div>
  </div>
  <div class="settings-panel" id="settingsPanel">
    <div class="settings-item" onclick="toggleDayMode()">白天模式</div>
    <div class="settings-item" onclick="toggleDarkMode()">夜间模式</div>
    <div class="settings-item" onclick="openAddressModal()">服务器地址</div>
  </div>
  <div class="modal" id="addressModal">
    <input type="text" id="addressInput" placeholder="输入服务器地址" />
    <button class="confirm-button" onclick="saveAddress()">确认</button>
    <button class="cancel-button" onclick="closeAddressModal()">取消</button>
  </div>
  <div id="confirmDialog" class="dialog hidden">
    <div class="dialog-content">
      <p>删除后将不会出现在你的记录中，确定删除吗？</p>
      <button id="confirmYes">确定</button>
      <button id="confirmNo">取消</button>
    </div>
  </div>
  <script>
    const chatWindow = document.querySelector('.chat-window');
    const chatHeader = document.querySelector('.chat-header');
    const chatBody = document.querySelector('.chat-body');
    const chatFooter = document.querySelector('.chat-footer');
    const messageInput = document.querySelector('input[type="text"]');
    const sendButton = document.querySelector('input[type="submit"]');
    const addressModal = document.querySelector('#addressModal');
    const addressInput = document.querySelector('#addressInput');
    let ws = null;
    let address = '127.0.0.1'; // 初始服务器IP地址
    let server_address = address; // 初始ws服务器地址

    function createWebSocket() {
      ws = new WebSocket(`ws://${server_address}:2023/`);
      // 监听WebSocket连接事件
      ws.addEventListener('open', (event) => {
        console.log('客户端 已连接');
      });

      // 监听WebSocket消息事件
      ws.addEventListener('message', (event) => {
        const message = JSON.parse(event.data);
        if (message.type === 'message') {
          const content = message.content;
      
          const messageWindow = document.createElement('div');
          messageWindow.className = 'message-window';
          const messageElement = document.createElement('div');
          messageElement.className = 'message';
      
          messageElement.innerHTML = `
            <div class="avatar"></div>
            <div class="content">${parseMessageContent(content)}</div>
          `;
      
          const deleteButton = document.createElement('button');
          deleteButton.className = 'text-neutral-300 transition hover:text-neutral-900 dark:text-neutral-600 dark:hover:text-neutral-300';
          deleteButton.style.border = 'none';
          deleteButton.style['background-color'] = 'transparent';
          deleteButton.style.fontSize = '6px';
          deleteButton.style.float = 'right';
          deleteButton.style.cursor = 'pointer';
          deleteButton.style['margin-bottom'] = '1px';
          deleteButton.title = '删除';
          deleteButton.innerHTML = '<svg t="1687940513319" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3173" width="13" height="13"><path d="M202.666667 256h-42.666667a32 32 0 0 1 0-64h704a32 32 0 0 1 0 64H266.666667v565.333333a53.333333 53.333333 0 0 0 53.333333 53.333334h384a53.333333 53.333333 0 0 0 53.333333-53.333334V352a32 32 0 0 1 64 0v469.333333c0 64.8-52.533333 117.333333-117.333333 117.333334H320c-64.8 0-117.333333-52.533333-117.333333-117.333334V256z m224-106.666667a32 32 0 0 1 0-64h170.666666a32 32 0 0 1 0 64H426.666667z m-32 288a32 32 0 0 1 64 0v256a32 32 0 0 1-64 0V437.333333z m170.666666 0a32 32 0 0 1 64 0v256a32 32 0 0 1-64 0V437.333333z" fill="#000000" p-id="3174"></path></svg>'; 
          const confirmDialog = document.getElementById('confirmDialog');
          const confirmYes = document.getElementById('confirmYes');
          const confirmNo = document.getElementById('confirmNo');
          deleteButton.onclick = function() {
            confirmDialog.classList.remove('hidden');
          };

          confirmYes.onclick = function() {
            deleteButton.parentNode.remove();
            confirmDialog.classList.add('hidden');
          };

          confirmNo.onclick = function() {
            confirmDialog.classList.add('hidden');
          };
      
          const copyButton = document.createElement('button');
          copyButton.className = 'text-neutral-300 transition hover:text-neutral-900 dark:text-neutral-600 dark:hover:text-neutral-300';
          copyButton.style.border = 'none';
          copyButton.style['background-color'] = 'transparent';
          copyButton.style.fontSize = '6px';
          copyButton.style.float = 'right';
          copyButton.style.cursor = 'pointer';
          copyButton.style['margin-bottom'] = '1px';
          copyButton.title = '复制';
          copyButton.innerHTML = '<svg t="1687940444536" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2130" width="12" height="12"><path d="M720 192h-544A80.096 80.096 0 0 0 96 272v608C96 924.128 131.904 960 176 960h544c44.128 0 80-35.872 80-80v-608C800 227.904 764.128 192 720 192z m16 688c0 8.8-7.2 16-16 16h-544a16 16 0 0 1-16-16v-608a16 16 0 0 1 16-16h544a16 16 0 0 1 16 16v608z" p-id="2131"></path><path d="M848 64h-544a32 32 0 0 0 0 64h544a16 16 0 0 1 16 16v608a32 32 0 1 0 64 0v-608C928 99.904 892.128 64 848 64z" p-id="2132"></path><path d="M608 360H288a32 32 0 0 0 0 64h320a32 32 0 1 0 0-64zM608 520H288a32 32 0 1 0 0 64h320a32 32 0 1 0 0-64zM480 678.656H288a32 32 0 1 0 0 64h192a32 32 0 1 0 0-64z" p-id="2133"></path></svg>';
          copyButton.onclick = function() {
            navigator.clipboard.writeText(content);
            showNotification('<div style="display: flex; align-items: center;"><span style="background-color: green; color: white; border-radius: 50%; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 12px; line-height: 12px;">&#10004;</span>&nbsp;&nbsp;<span style="font-size: 12px; line-height: 12px;">复制成功</span></div>', 'info');
          };
      
          messageWindow.appendChild(messageElement);
          messageWindow.appendChild(deleteButton);
          messageWindow.appendChild(copyButton);
          chatBody.appendChild(messageWindow);
          chatBody.scrollTop = chatBody.scrollHeight;
        }
      });
    }

    function sendMessage(event) {
      event.preventDefault();
      const message = messageInput.value;
      if (message.trim()) {
        ws.send(JSON.stringify({
          type: 'message',
          content: message.toString()
        }));
        const messageWindow = document.createElement('div');
        messageWindow.className = 'message-window';
        const messageElement = document.createElement('div');
        messageElement.className = 'message sent';
        messageElement.innerHTML = `
          <div class="content">${parseMessageContent(message)}</div>
          <div class="avatar"></div>
        `;
        const deleteButton = document.createElement('button');
        deleteButton.className = 'text-neutral-300 transition hover:text-neutral-900 dark:text-neutral-600 dark:hover:text-neutral-300';
        deleteButton.style.border = 'none';
        deleteButton.style['background-color'] = 'transparent';
        deleteButton.style.fontSize = '6px';
        deleteButton.style.float = 'right';
        deleteButton.style.cursor = 'pointer';
        deleteButton.style['margin-bottom'] = '1px';
        deleteButton.title = '删除';
        deleteButton.innerHTML = '<svg t="1687940513319" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3173" width="13" height="13"><path d="M202.666667 256h-42.666667a32 32 0 0 1 0-64h704a32 32 0 0 1 0 64H266.666667v565.333333a53.333333 53.333333 0 0 0 53.333333 53.333334h384a53.333333 53.333333 0 0 0 53.333333-53.333334V352a32 32 0 0 1 64 0v469.333333c0 64.8-52.533333 117.333333-117.333333 117.333334H320c-64.8 0-117.333333-52.533333-117.333333-117.333334V256z m224-106.666667a32 32 0 0 1 0-64h170.666666a32 32 0 0 1 0 64H426.666667z m-32 288a32 32 0 0 1 64 0v256a32 32 0 0 1-64 0V437.333333z m170.666666 0a32 32 0 0 1 64 0v256a32 32 0 0 1-64 0V437.333333z" fill="#000000" p-id="3174"></path></svg>';
        const confirmDialog = document.getElementById('confirmDialog');
        const confirmYes = document.getElementById('confirmYes');
        const confirmNo = document.getElementById('confirmNo');
        deleteButton.onclick = function() {
          confirmDialog.classList.remove('hidden');
        };

        confirmYes.onclick = function() {
          deleteButton.parentNode.remove();
          confirmDialog.classList.add('hidden');
        };

        confirmNo.onclick = function() {
          confirmDialog.classList.add('hidden');
        };

        const copyButton = document.createElement('button');
        copyButton.className = 'text-neutral-300 transition hover:text-neutral-900 dark:text-neutral-600 dark:hover:text-neutral-300';
        copyButton.style.border = 'none';
        copyButton.style['background-color'] = 'transparent';
        copyButton.style.fontSize = '6px';
        copyButton.style.float = 'right';
        copyButton.style.cursor = 'pointer';
        copyButton.style['margin-bottom'] = '1px';
        copyButton.title = '复制';
        copyButton.innerHTML = '<svg t="1687940444536" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2130" width="12" height="12"><path d="M720 192h-544A80.096 80.096 0 0 0 96 272v608C96 924.128 131.904 960 176 960h544c44.128 0 80-35.872 80-80v-608C800 227.904 764.128 192 720 192z m16 688c0 8.8-7.2 16-16 16h-544a16 16 0 0 1-16-16v-608a16 16 0 0 1 16-16h544a16 16 0 0 1 16 16v608z" p-id="2131"></path><path d="M848 64h-544a32 32 0 0 0 0 64h544a16 16 0 0 1 16 16v608a32 32 0 1 0 64 0v-608C928 99.904 892.128 64 848 64z" p-id="2132"></path><path d="M608 360H288a32 32 0 0 0 0 64h320a32 32 0 1 0 0-64zM608 520H288a32 32 0 1 0 0 64h320a32 32 0 1 0 0-64zM480 678.656H288a32 32 0 1 0 0 64h192a32 32 0 1 0 0-64z" p-id="2133"></path></svg>';
        
        copyButton.onclick = function() {
            const textArea = document.createElement('textarea');
            textArea.value = content;
            document.body.appendChild(textArea);
            textArea.select();
            document.execCommand('copy');
            document.body.removeChild(textArea);
            showNotification('<div style="display: flex; align-items: center;"><span style="background-color: green; color: white; border-radius: 50%; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 12px; line-height: 12px;">&#10004;</span>&nbsp;&nbsp;<span style="font-size: 12px; line-height: 12px;">复制成功</span></div>', 'info');
          };
        messageWindow.appendChild(messageElement);
        messageWindow.appendChild(deleteButton);
        messageWindow.appendChild(copyButton);
        chatBody.appendChild(messageWindow);
        chatBody.scrollTop = chatBody.scrollHeight;
        messageInput.value = '';
      }
    }

    function showNotification(message, type) {
      const notification = document.createElement('div');
      notification.className = `notification ${type}`;
      notification.style.display = 'flex';
      notification.style.alignItems = 'center';
      notification.style.justifyContent = 'center';
      notification.innerHTML = `<div class="notification-content">${message}</div>`;

      // 获取 .chat-header 元素的位置和尺寸
      const chatHeader = document.querySelector('.chat-header');
      const { height } = chatHeader.getBoundingClientRect();

      // 计算悬浮通知应该放置的位置
      notification.style.position = 'absolute';
      notification.style.top = `${height / 2}px`;

      document.body.appendChild(notification);
      setTimeout(() => {
        notification.remove();
      }, 3000);
    }

    function parseMessageContent(content) {
      // 替换特殊字符
      content = content.replace(/</g, '&lt;').replace(/>/g, '&gt;');
      // 解析链接
      if (window.utools) {
        content = content.replace(/(https?:\/\/[^\s]+)/g, (match, url) => {
          return `<a href="#" onclick="utools.shellOpenExternal('${url}');">${url}</a>`;
        });
      } else {
        content = content.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank">$1</a>');
      }
      // 处理换行
      content = content.replace(/\n/g, '<br/>');
      return content;
    }

    sendButton.addEventListener('click', sendMessage);
    messageInput.addEventListener('keydown', function(event) {
      if (event.key === 'Enter') {
        sendMessage(event);
      }
    });

    // 监听设置按钮
    function toggleSettingsPanel() {
      const settingsPanel = document.getElementById('settingsPanel');
      settingsPanel.classList.toggle('active');
    }

    // 监听黑夜按钮
     function toggleDarkMode() {
      chatWindow.classList.add('dark-mode');
      chatHeader.classList.add('dark-mode');
      chatBody.classList.add('dark-mode');
      chatFooter.classList.add('dark-mode');
    }

    // 监听白天按钮
    function toggleDayMode() {
      chatWindow.classList.remove('dark-mode');
      chatHeader.classList.remove('dark-mode');
      chatBody.classList.remove('dark-mode');
      chatFooter.classList.remove('dark-mode');
    }

    // 打开服务器地址模态框
    function openAddressModal() {
      addressInput.value = server_address; // 只显示IP地址
      addressModal.classList.add('active');
    }

    // 保存服务器地址
    function saveAddress() {
      const newAddress = addressInput.value.trim();
      if (validateIPAddress(newAddress) && !startsWith255(newAddress)) {
        ws.close(); // 先关闭旧的WebSocket连接
        server_address = newAddress; // 更新地址变量
        createWebSocket(); // 创建新的WebSocket连接
        addressModal.classList.remove('active'); // 关闭模态框
      } else {
        addressInput.style.borderColor = 'red'; // 设置边框颜色为红色
        addressInput.classList.add('shake'); // 添加震动效果
        setTimeout(() => {
          addressInput.classList.remove('shake'); // 移除震动效果
        }, 500);
      }
    }

    // 关闭服务器地址模态框
    function closeAddressModal() {
      addressModal.classList.remove('active');
    }

    // 校验IP地址的格式是否合法
    function validateIPAddress(ip) {
      const ipRegex = /^(25[0-4]|2[0-4]\d|1\d{2}|[1-9]\d|\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)){3}$/;
      return ipRegex.test(ip);
    }

    // 判断IP地址是否以255开头
    function startsWith255(ip) {
      const ipParts = ip.split('.');
      return ipParts[0] === '255';
    }

    // 监听输入框的输入事件，重置边框颜色
    addressInput.addEventListener('input', function() {
      addressInput.style.borderColor = '';
    });

    // 创建初始的WebSocket连接
    createWebSocket();
  </script>
</body>
</html>
